package high.concurrent.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 优惠券锁定MQ延迟检查
 */
@Configuration
public class LockCouponRecordMQConfig {

    /**
     * 死信队列的交换机， 队列， 路由key
     */
    public static final String EXCHANGE_NAME = "COUPON_RECORD_EXCHANGE";
    public static final String QUEUE_NAME = "LOCK_COUPON_RECORD_QUEUE";
    public static final String ROUTING_KEY = "LOCK_COUPON_RECORD_ROUTING_KEY";

    /**
     * 消息转换器，转成Json，这么写就行
     * @return
     */
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }
    /**
     * 初始化【死信队列 与 延迟队列】交换机，通过创造模式
     * 选用topic类型交换机 ， 进行durable=true持久化
     * @return
     */
    @Bean(value = "couponrecord_exchange_job")
    public Exchange getExchangeJob(){
        return ExchangeBuilder.topicExchange(EXCHANGE_NAME) .durable(true).build();
    }

    /**
     * 初始化【死信队列】队列，通过创造模式
     * 进行durable配置队列名
     * @return
     */
    @Bean(value = "lock_couponrecord_queue_job")
    public Queue getQueueJob(){
        return QueueBuilder.durable(QUEUE_NAME).build();
    }

    /**
     * 绑定死信【队列】与【交换机】
     * @param exchange  指定的交换机名，注意用@Qualifier(value = "lock_couponrecord_exchange_job")指定名称
     * @param queue     指定的队列名，注意用@Qualifier("lock_couponrecord_queue_job")指定名称
     * bing(队列).to(交换机).with(路由规则).noargs();
     * 路由规则注意*与#
     * @return
     */
    @Bean
    public Binding bingExchangeQueue(@Qualifier("lock_couponrecord_queue_job") Queue queue,
                                     @Qualifier("couponrecord_exchange_job") Exchange exchange){

        return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY).noargs();
    }


    /**
     * 普通延迟队列， 路由key
     */
    public static final String DELAY_QUEUE_NAME = "DELAY_COUPON_RECORD_QUEUE";
    public static final String DELAY_ROUTING_KEY = "DELAY_COUPON_RECORD_ROUTING_KEY";


    /**
     * 初始化【延迟队列】队列，通过创造模式
     * 进行durable配置队列名
     * @return
     */
    @Bean(value = "delay_couponrecord_queue_job")
    public Queue getDelayQueueJob(){

        // 普通队列绑定的到死信队列，当过期时，将消息转发到死信队列
        Map<String, Object> map = new HashMap<>(3);
        // 消息过期后，进入到的死信交换机
        map.put("x-dead-letter-exchange", EXCHANGE_NAME);
        // 消息过期后，匹配的死信路由，结合死信交换机进入指定的死信队列
        map.put("x-dead-letter-routing-key", ROUTING_KEY);
        // 消息过期时间为10000ms， 单位ms
        map.put("x-message-ttl", 10000);

        return QueueBuilder.durable(DELAY_QUEUE_NAME).withArguments(map).build();
    }

    /**
     * 绑定延迟【队列】与【交换机】
     * @param exchange  指定的交换机名，注意用@Qualifier(value = "delay_couponrecord_exchange_job")指定名称
     * @param queue     指定的队列名，注意用@Qualifier("delay_couponrecord_queue_job")指定名称
     * bing(队列).to(交换机).with(路由规则).noargs();
     * 路由规则注意*与#
     * @return
     */
    @Bean
    public Binding bingDelayExchangeQueue(@Qualifier("delay_couponrecord_queue_job") Queue queue,
                                     @Qualifier("couponrecord_exchange_job") Exchange exchange){

        return BindingBuilder.bind(queue).to(exchange).with(DELAY_ROUTING_KEY).noargs();
    }
}
